﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using MsForgeReboot.Framework.Entities;

namespace MsForgeReboot.Web.Extensions {
    public class OldLogin {
            /// <summary>
            /// The user's profile record.
            /// </summary>
            private User userProfile;

            /// <summary>
            /// The users membership record.
            /// </summary>
            private Membership membership;

            /// <summary>
            /// The clear text password.
            /// </summary>
            private string clearPassword;

            /// <summary>
            /// The password after it has been hashed using SHA1.
            /// </summary>
            private string sha1HashedPassword;

            /// <summary>
            /// The user's user name.
            /// </summary>
            private string userName;

            /// <summary>
            /// Inidcates if the authentication token in the cookie should be persisted beyond the current session.
            /// </summary>
            private bool persistCookie;

            /// <summary>
            /// Validates the user against legacy values.
            /// </summary>
            /// <param name="userName">The user's UserName.</param>
            /// <param name="password">The user's password.</param>
            /// <param name="persistCookie">Inidcates if the authentication token in the cookie should be persisted beyond the current session.</param>
            /// <returns>true if the user is validated and logged in, otherwise false.</returns>
            public bool Login(string userName, string password, bool persistCookie = false) {
                this.userName = userName;
                this.clearPassword = password;
                this.persistCookie = persistCookie;

                if (!GetOriginalValues()) {
                    return false;
                }

                SetHashedPassword();

                if (this.sha1HashedPassword != this.membership.Password) {
                    return false;
                }

                this.SetPasswordAndLoginUser();

                return true;
            }

            /// <summary>
            /// Gets the original password values
            /// </summary>
            protected bool GetOriginalValues() {
                using (var context = new MsForgeReboot.Services.MsForgeContext()) {
                    this.userProfile = context.Users.Where(x => x.Username.ToLower() == userName.ToLower()).SingleOrDefault();

                    if (this.userProfile == null) {
                        return false;
                    }

                    this.membership = context.Memberships.Where(x => x.UserId == this.userProfile.Id).SingleOrDefault();

                    if (this.membership == null) {
                        return false;
                    }

                    if (!this.membership.IsConfirmed) {
                        return false;
                    }
                }

                return true;
            }

            /// <summary>
            /// Encrypts the password using the SHA1 algorithm.
            /// </summary>
            /// <remarks>
            /// Many thanks to Malcolm Swaine for the hashing code.
            /// http://www.codeproject.com/Articles/32600/Manually-validating-an-ASP-NET-user-account-with-a
            /// </remarks>
            protected void SetHashedPassword() {
                byte[] bIn = Encoding.Unicode.GetBytes(clearPassword);
                byte[] bSalt = Convert.FromBase64String(membership.PasswordSalt);
                byte[] bAll = new byte[bSalt.Length + bIn.Length];
                byte[] bRet = null;
                Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
                Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);

                HashAlgorithm s = HashAlgorithm.Create("SHA1");
                bRet = s.ComputeHash(bAll);
                string newHash = Convert.ToBase64String(bRet);
                this.sha1HashedPassword = newHash;
            }

            /// <summary>
            /// Sets the password using the new algorithm and perofrms a login.
            /// </summary>
            protected void SetPasswordAndLoginUser() {
                var token = WebMatrix.WebData.WebSecurity.GeneratePasswordResetToken(this.userName, 2);
                WebMatrix.WebData.WebSecurity.ResetPassword(token, clearPassword);
                WebMatrix.WebData.WebSecurity.Login(userName, clearPassword, persistCookie);
            }
    }
}